package mogiksaop.qliphoth;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;

public class RandomHelper {
	public static final Random rand = new Random();

	public static int getRandomNumberBetween(int min, int max) {
		return useRandomForNumberBetween(rand, min, max);
	}

	public static float getRandomNumberBetween(float min, float max) {
		return useRandomForNumberBetween(rand, min, max);
	}

	public static int[] getRandomDistinctNumbersBetween(int min, int max, int numElements) {
		int totalNumbers = max - min + 1;
		if (numElements < 1) {
			return new int[0];
		}
		if (numElements > totalNumbers) {
			numElements = totalNumbers;
		}

		int[] randomNumbers = new int[numElements];
		List<Integer> allNumbers = new ArrayList<Integer>(totalNumbers);
		for (int i = 0; i < totalNumbers; i++) {
			allNumbers.add(Integer.valueOf(min + i));
		}
		for (int i = 0; i < numElements; i++) {
			randomNumbers[i] = ((Integer) getRandomElementFromList(allNumbers)).intValue();
			allNumbers.remove(new Integer(randomNumbers[i]));
		}
		return randomNumbers;
	}

	public static int useRandomForNumberBetween(Random random, int min, int max) {
		return random.nextInt(max - min + 1) + min;
	}

	public static float useRandomForNumberBetween(Random random, float min, float max) {
		return random.nextFloat() * (max - min) + min;
	}

	public static <T> T getRandomElementFromList(List<T> list) {
		if (!list.isEmpty()) {
			return (T) list.get(getRandomNumberBetween(0, list.size() - 1));
		}
		return null;
	}

	public static <T> T getRandomElementFromArray(T[] array) {
		if (array == null || array.length == 0) {
			return null;
		}
		return array[getRandomNumberBetween(0, array.length - 1)];
	}

	public static <T> T removeRandomElementFromList(List<T> list) {
		if (!list.isEmpty()) {
			return (T) list.remove(getRandomNumberBetween(0, list.size() - 1));
		}
		return null;
	}

	public static boolean getRandomChance(double chance) {
		return (rand.nextDouble() < chance);
	}

	public static boolean getRandomChance(float chance) {
		return (rand.nextFloat() < chance);
	}

	public static boolean getRandomChance(int chance) {
		return getRandomChance(chance / 100.0F);
	}

	public static boolean getRandomChance() {
		return getRandomChance(0.5F);
	}

	public static int getFortuneAmount(int fortune) {
		return (fortune > 0) ? Math.max(1, rand.nextInt(fortune + 2)) : 1;
	}

	public static void initXZSeed(Random random, World world, int chunkX, int chunkZ) {
		long seed = (world == null) ? 0L : world.getSeed();
		seed *= (seed * 6364136223846793005L + 1442695040888963407L);
		seed += chunkX;
		seed *= (seed * 6364136223846793005L + 1442695040888963407L);
		seed += chunkZ;
		seed *= (seed * 6364136223846793005L + 1442695040888963407L);
		seed += chunkX;
		seed *= (seed * 6364136223846793005L + 1442695040888963407L);
		seed += chunkZ;
		random.setSeed(seed);
	}

	public static Random staticRandomWithXZSeed(World world, int chunkX, int chunkZ) {
		initXZSeed(rand, world, chunkX, chunkZ);
		return rand;
	}

	public static int getRandomIndexFromWeights(List<Integer> weights) {
		int totalWeight = 0;

		for (Integer weight : weights) {
			totalWeight += weight.intValue();
		}

		if (totalWeight > 0) {
			int num = getRandomNumberBetween(0, totalWeight - 1);
			int sum = 0;
			for (int i = 0; i < weights.size(); i++) {
				sum += ((Integer) weights.get(i)).intValue();

				if (num < sum)
					return i;
			}
		}
		return -1;
	}
}